package com.zihao;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.TextView;
import brut.androlib.res.AndrolibResources;
import brut.common.BrutException;
import com.guye.baffle.exception.BaffleException;
import com.zihao.R;
import com.zihao.view.CircularProgressButton;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Vector;
import org.zeroturnaround.zip.ZipUtil;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.net.Uri;

public class MainActivity extends Activity 
{
	public static void startThisActivity(Activity activity) {
        activity.startActivity(new Intent(activity, MainActivity.class));
    }
	public static String path= Environment.getExternalStorageDirectory ( ).getPath ( ) + "/工程";
	String out = path + "/加固";
	public Vector addm;
	public static String odexPath;
	CircularProgressButton 加密;
	ProgressBar progress;
	TextView log;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
		//创建解压目标目录  
		File file = new File(path);  
		//如果目标目录不存在，则创建  
		if (!file.exists()) {  
			file.mkdirs();  
		} 
		Print p=new Print ( h );
        brut.apktool.Main.setLog ( p );
		File odex = this.getDir ( "cache", MODE_PRIVATE );
        odexPath  = odex.getAbsolutePath ( );
        zip ( );
        AndrolibResources.setr9s ( new Res9 ( ) );
        pulsh ( );
        aapt.aapt ( );
		if ( Build.VERSION.SDK_INT < 21 )
		{
            String[]  aimpath =new String[]{"if","/system/framework/framework-res.apk"};
            try
			{
                brut.apktool.Main.main ( aimpath );
			}
            catch (InterruptedException e)
			{}
            catch (BrutException e)
			{}
            catch (IOException e)
			{}
		}
		progress = (ProgressBar) findViewById(R.id.progress);
		加密=(CircularProgressButton) findViewById(R.id.加密);
		log = (TextView) findViewById(R.id.log);
		progress.setMax ( 9 );
		加密.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View p1)
				{
					加密.setClickable(false);
					加密.setIndeterminateProgressMode(true);
					addm = GetAPK ( path );
					if ( addm.isEmpty ( ) )
                    {
						h.sendEmptyMessage ( 10 );
						return;
                   }
							/*
							 自动so
							 */
							new Thread ( ){
								public void run ( )
                                {
									try
                                    {
										h.sendEmptyMessage ( 0 );
										Thread.sleep(1000);
										h.sendEmptyMessage ( 1 );
										Thread.sleep(1000);
										//开始反编译
										String[] main=new String[] {"d","-f","-s",path + "/" + addm.get ( 0 ).toString ( ),"-o",out};
										brut.apktool.Main.main ( main );
                                    }
									catch (InterruptedException e)
                                    {
										h.sendEmptyMessage ( 2 );
									}
									catch (BrutException e)
                                    {
										h.sendEmptyMessage ( 2 );
									}
									catch (IOException e)
                                    {
										h.sendEmptyMessage ( 2 );
									}
									//--------------AndroidManifest.xml开始处理---------------
									h.sendEmptyMessage ( 3 );
									String tmp,zihao="",Kin="",king="";
									File f=null;
									f = new File ( out + "/AndroidManifest.xml" );
									InputStream in = null;
									try
                                    {
										in = new BufferedInputStream ( new FileInputStream ( f ) );
                                    }
									catch (FileNotFoundException e3)
                                    {
										e3.printStackTrace ( );
                                    }
									BufferedReader br = null;
									try
                                    {
										br = new BufferedReader ( new InputStreamReader ( in, "gb2312" ) );
                                    }
									catch (UnsupportedEncodingException e1)
                                    {
										e1.printStackTrace ( );
                                    }
									try
                                    {
										while ( ( tmp = br.readLine ( ) ) != null )
                                        {
											zihao = zihao + tmp + "\n";
                                        }
										br.close ( );
										in.close ( );
										f.delete ( );
                                    }
									catch (IOException e)
                                    {
										e.printStackTrace ( );
                                    }
									String[] strarray=zihao.split ( "\n" ); 
									for ( int i = 0; i < strarray.length; i++ ) 
                                    {
										if ( strarray [ i ].indexOf ( "<application" ) != -1 )
                                        {
											if ( strarray [ i ].indexOf ( "android:name" ) != -1 )
                                            {
												String kk="";
												String[] buff=strarray [ i ].split ( " " );
												for ( int di = 0; di < buff.length; di++ ) 
                                                {
													if ( buff [ di ].indexOf ( "android:name" ) != -1 )
                                                    {
														king = buff [ di ].toString ( ).replace ( "name", "value" );
														// System.out.println ( "二次修改过的_" + k );
														buff [ di ] = " ";
                                                    }
													kk = kk + buff [ di ] + " ";
													//System.out.println ( "第二次分  " + buff [ di ] );
                                                }
												strarray [ i ] = kk;
                                            }
											if ( king.isEmpty ( ) )
                                            {
												strarray [ i ] = strarray [ i ].toString ( ) .replace ( ">", " android:name=\"com.StubShell.StubShell\">\n            <meta-data\nandroid:name=\"KING-子豪\"\nandroid:value=\"QQ:1365036395\"/>" );
                                            }
											else
                                            {
																strarray [ i ] = strarray [ i ].toString ( ).replace ( ">", " android:name=\"com.StubShell.StubShell\">\n            <meta-data\nandroid:name=\"KING-子豪\"\n " + king + "/>" );
                                            }
                                        }
										Kin = Kin + strarray [ i ].toString ( ) + "\n";
                                    }
									//--------------Androidmanidfest.xml处理完成---------------
									h.sendEmptyMessage ( 4 );
									try
                                    {
										//删除原始androidmanifest.xml
										f.delete ( );
										//创建新的
										f.createNewFile ( );
										//写入数据
										writeFile ( f.getAbsolutePath ( ), Kin );
										//反编译dex
										String[] bu=new String[]{"-o",path + "/加固/dex",path + "/加固/classes.dex"};
										org.jf.baksmali.main.main ( bu );
										h.sendEmptyMessage ( 5 );
										//开始编译dex
										String[] ba=new String[]{path + "/加固/dex","-o",path + "/加固/classes.dex"};
										org.jf.smali.main. main ( ba );
										//删除反编译的dex目录
										DeleteFile ( new File ( path + "/加固/dex" ) );
										//加密dex
										h.sendEmptyMessage ( 6 );
										FileEncryptUtils.encryptFile ( "37F582E3DFF6343B8FD1D62B58F8E946",  path + "/加固/classes.dex",   path + "/加固/assets/Code.dat" );
										//删除原dex
										File ad=new File ( path + "/加固/classes.dex" );
										ad.delete ( );
										//解压新的dex
										b ( );
										//解压so加载库
										ZipUtil.unpack ( new File ( path + "/加固/StubShell.zip" ), new File ( path + "/加固" ) );
										//删除临时文件
										File bbb=new File ( path + "/加固/StubShell.zip" );
										bbb.delete ( );
										//开始编译APK
										h.sendEmptyMessage ( 7 );
										String[] maini=new String[] {"b","-f","-a",odexPath + "/aapt",out,"-o",out.replace ( "加固", "已加固.apk" )};
										brut.apktool.Main.main ( maini );
										h.sendEmptyMessage ( 8 );
										//删除临时文件目录
										DeleteFile ( new File ( path + "/加固" ) );
										//对编译的apk进行资源混淆
										String[] abd=new String[]{path + "/已加固.apk",path + "/已加固[未签名].apk"};
										com.guye.baffle.obfuscate.Main.main ( abd );
										//删除不需要的APK
										File da=new File ( path + "/已加固.apk"  );
										da.delete ( );
										h.sendEmptyMessage ( 9 );
                                    }
									catch (IOException e)
                                    {
										h.sendEmptyMessage ( 2 );
									}
									catch (InterruptedException e)
                                    {
										h.sendEmptyMessage ( 2 );
									}
									catch (BrutException e)
                                    {
										h.sendEmptyMessage ( 2 );
									}
									catch (BaffleException e)
                                    {
										h.sendEmptyMessage ( 2 );
									}
                                }
                            }.start ( );
				}
			});
		}
	Handler h =new Handler ( )
	{
        @Override
        public void handleMessage ( Message msg )
		{
            switch ( msg.what )
			{
                case 0:
					progress.setProgress(0);
					加密.setProgress(50);
					progress.incrementProgressBy ( 1 );
					log.setText ( "加固开始!" );
					break;
				case 1:
					progress.incrementProgressBy ( 1 );
					log.setText("处理文件:"+addm.get(0).toString());
					break;
				case 2:
					加密.setProgress(-1);
					log.setText("程序出现异常!");
					加密.setProgress(0);
					progress.setProgress(0);
					加密.setClickable(true);
					break;
				case 3:
					progress.incrementProgressBy ( 1 );
					log.setText("处理AndroidManifest.xml中...");
				break;
				case 4:
					progress.incrementProgressBy ( 1 );
					log.setText("AndroidManifest.xml处理完成!");
				break;
				case 5:
					progress.incrementProgressBy ( 1 );
					log.setText("编译classes.dex中...");
				break;
				case 6:
					progress.incrementProgressBy ( 1 );
					log.setText("释放核心文件");
				break;
				case 7:
					progress.incrementProgressBy ( 1 );
					log.setText("编译打包APK");
				break;
				case 8:
					progress.incrementProgressBy ( 1 );
					log.setText("资源优化混淆中...");
				break;
				case 9:
					加密.setProgress(100);
					progress.incrementProgressBy ( 1 );
					log.setText("APK加固成功,请手动签名!");
					dialog("APK加固成功,请手动签名!");
					progress.setProgress(0);
					加密.setClickable(true);
				break;
				case 10:
					加密.setProgress(-1);
					log.setText(path+"目录没有APK文件!");
					dialog( path + "目录没有APK文件!");
					加密.setClickable(true);
				break;
			}
            super.handleMessage ( msg );
		}
	};
	public static Vector<String> GetAPK ( String fileAbsolutePath )
	{
        Vector<String> vecFile = new Vector<String> ( );
        File file = new File ( fileAbsolutePath );
        File[] subFile = file.listFiles ( );
        for ( int iFileLength = 0; iFileLength < subFile.length; iFileLength++ )
		{
            if ( !subFile [ iFileLength ].isDirectory ( ) )
			{
                String filename = subFile [ iFileLength ].getName ( );
                if ( filename.trim ( ).toLowerCase ( ).endsWith ( ".apk" ) )
				{
                    vecFile.add ( filename );
				}
			}
		}
        return vecFile;
	}
	private void zip ( )
	{
        try
		{
            InputStream localInputStream = getClass ( ).getResource ( "/zipalign" ).openStream ( );
            FileOutputStream localFileOutputStream = new FileOutputStream ( new File ( odexPath + "/",
                                                                                      "zipalign" ) );
            byte[] arrayOfByte = new byte[1024];
            for ( ;; )
			{
                int i = localInputStream.read ( arrayOfByte );
                if ( i == -1 )
				{
                    break;
				}
                localFileOutputStream.write ( arrayOfByte, 0, i );
                localFileOutputStream.flush ( );
			}
            localFileOutputStream.close ( );
            localInputStream.close ( );
		}
        catch (IOException e)
		{
            e.printStackTrace ( );
            return;
		}
	}
    private void pulsh ( )
	{
        try
		{
            InputStream localInputStream = getClass ( ).getResource ( "/aapt" ).openStream ( );
            FileOutputStream localFileOutputStream = new FileOutputStream ( new File (  odexPath + "/",
                                                                                      "aapt" ) );
            byte[] arrayOfByte = new byte[1024];
            for ( ;; )
			{
                int i = localInputStream.read ( arrayOfByte );
                if ( i == -1 )
				{
                    break;
				}
                localFileOutputStream.write ( arrayOfByte, 0, i );
                localFileOutputStream.flush ( );
			}
            localFileOutputStream.close ( );
            localInputStream.close ( );
		}
        catch (IOException e)
		{
            e.printStackTrace ( );
            return;
		}
	}
	private void b ( )
	{
        try
		{
            InputStream localInputStream = getClass ( ).getResource ( "/Code" ).openStream ( );
            FileOutputStream localFileOutputStream = new FileOutputStream ( new File ( path + "/加固",
                                                                                      "StubShell.zip" ) );
            byte[] arrayOfByte = new byte[1024];
            for ( ;; )
			{
                int i = localInputStream.read ( arrayOfByte );
                if ( i == -1 )
				{
                    break;
				}
                localFileOutputStream.write ( arrayOfByte, 0, i );
                localFileOutputStream.flush ( );
			}
            localFileOutputStream.close ( );
            localInputStream.close ( );
		}
        catch (IOException e)
		{
            e.printStackTrace ( );
            return;
		}
	}
	public void DeleteFile ( File file )
	{ 
        if ( file.exists ( ) == false )
		{ 
            return; 
		}
        else
		{ 
            if ( file.isFile ( ) )
			{ 
                file.delete ( ); 
                return; 
			} 
            if ( file.isDirectory ( ) )
			{ 
                File[] childFile = file.listFiles ( ); 
                if ( childFile == null || childFile.length == 0 )
				{ 
                    file.delete ( ); 
                    return; 
				} 
                for ( File f : childFile )
				{ 
                    DeleteFile ( f ); 
				} 
                file.delete ( ); 
			} 
		} 
	} 
	public boolean deleteDirectory ( String filePath )
	{
        boolean flag = false;
        if ( !filePath.endsWith ( File.separator ) )
		{
            filePath = filePath + File.separator;
		}
        File dirFile = new File ( filePath );
        if ( !dirFile.exists ( ) || !dirFile.isDirectory ( ) )
		{
            return false;
		}
        flag = true;
        File[] files = dirFile.listFiles ( );
        for ( int i = 0; i < files.length; i++ )
		{
            if ( files [ i ].isFile ( ) )
			{
                flag = deleteFile ( files [ i ].getAbsolutePath ( ) );
                if ( !flag ) break;
			}
            else
			{
                flag = deleteDirectory ( files [ i ].getAbsolutePath ( ) );
                if ( !flag ) break;
			}
		}
        if ( !flag ) return false;
        return dirFile.delete ( );
	}
    /*
     拷贝文件函数
     */
    public boolean copyFile ( String oldPath, String newPath )
	{ 
        boolean isok = true;
        try
		{ 
            int bytesum = 0; 
            int byteread = 0; 
            File oldfile = new File ( oldPath ); 
            if ( oldfile.exists ( ) )
			{ 
                InputStream inStream = new FileInputStream ( oldPath ); //读入原文件 
                FileOutputStream fs = new FileOutputStream ( newPath ); 
                byte[] buffer = new byte[1024]; 
                while ( ( byteread = inStream.read ( buffer ) ) != -1 )
				{ 
                    bytesum += byteread; 
                    fs.write ( buffer, 0, byteread ); 
				} 
                fs.flush ( ); 
                fs.close ( ); 
                inStream.close ( ); 
			}
            else
			{
                isok = false;
			}
		} 
        catch (Exception e)
		{ 
            isok = false;
		} 
        return isok;
	} 
	public static void writeFile ( String fileName, String writestr )
	{ 
        try
		{ 
            FileOutputStream fout = new FileOutputStream ( fileName );  
            byte [] bytes = writestr.getBytes ( "UTF-8" ); 
            fout.write ( bytes ); 
            fout.close ( ); 
		} 
        catch (Exception e)
		{ 
            e.printStackTrace ( ); 
		} 
	} 
	void print ( String s )
	{
        Message m=new Message ( );
        m.what = 100;
        m.obj = s;
        h.sendMessage ( m );
	}
    class Print implements brut.androlib.Log
	{
        @Override
        public void write_out ( byte[] p1 ) throws IOException
		{
            String msg=new String ( p1 );
            Message m=new Message ( );
            if ( msg.indexOf ( "W:" ) != -1 )
			{
                m.what = 100;
                m.obj = msg;
                h.sendMessage ( m );
                return;
			}
		}
        @Override
        public void write_err ( byte[] p1 ) throws IOException
		{
            String msg=new String ( p1 );
            Message m=new Message ( );

            if ( msg.indexOf ( "W:" ) != -1 )
			{
                if ( msg.indexOf ( "AndroidManifest.xml" ) != -1 )
				{
				}
                else
				{
                    m.what = 100;
                    m.obj = msg;
                    h.sendMessage ( m );
                    return;
				}
			}
		}
        Handler h;
        Print ( Handler h )
		{
            this.h = h;
		}
	}
	public void dialog(String a){
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setTitle(R.string.app_name); 
        builder.setMessage(a); 
        builder.setIcon(R.drawable.ic_launcher);
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss(); 
					加密.setProgress(0);
				}
			});
        builder.create().show();
    }
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.more, menu);
        return true;
    }
    
// 菜单点击事件
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.qq:
                Intent add=new Intent();
		
                add.setData(Uri.parse("mqqwpa://im/chat?chat_type=wpa&uin="+"2659593323"+"&version=1"));
		
                startActivity(add);
                break;
            case R.id.qun:
              Intent aq=new Intent();
	
              String qun="366684487";
              aq.setData(Uri.parse("mqqapi://card/show_pslcard?src_type=internal&version=1&uin="+qun+"&card_type=group&source=qrcode"));
		
              startActivity(aq);
             
                break;
                case R.id.tc:
                   MainActivity.this.finish();
                    break;
                    case R.id.help:
                        break;
        }
        return super.onOptionsItemSelected(item);
    }

}
